/**
	Copyright (c) 2010 ATTi 
	All rights reserved.
	Author: Michael Shu
	Date: 2/19/2010
*/
@isTest

// user as Opportunity/OpportunityLineItem Trigger coding unit test class, sorry for the Confusion of the test clase name
//    1. OppForNatSalesHelperClass.cls
//    2. OpportunityProductCheckForAAS.trigger
//    3. QuoteAASFieldUpdate.trigger
//    4. AASOpportunityMonthlyUpdate.cls
//    5. CaseProductNatoUpdate.trigger
//    6. caseUpdateContactAccountClass.cls
//

/*
   AD-24230, Quote status update, updated by Paul Lo, 10/12/11:
   
   RFP Draft -> Quote Draft
   RFP Submitted -> Quote Requested
   Proposal Submitted -> Quote Returned 
*/

private class OpportunitySharkPoolTriggerTester {	
	public static testMethod void testOppForNatSalesHelperClass() {
		//IDC 01/14/2012: Added Helper method for getting the Record Type instead of using SOQL
        ID oppContractRecrodTypeId = RecordTypeHelper.GetRecordTypeID('Opportunity', 'Contract'); 
		
		/*
		List<RecordType> recordTypes = [Select r.Id, r.Name, r.SobjectType from RecordType r where SobjectType = 'Opportunity' and Name = 'Contract'];
		String oppContractRecrodTypeId;
		if(!recordTypes.isEmpty()){
			oppContractRecrodTypeId = recordTypes[0].Id;
		}
		*/
		Opportunity o = new Opportunity();
		o.Name = 'testOppForNatSalesHelperClass';
		o.StageName = 'Pending Sale';
		o.CloseDate = Date.today().addDays(5);
		o.RecordTypeId = oppContractRecrodTypeId;
		Database.SaveResult sr_opp = Database.insert(o,false);
		
		Opportunity o_saved = [select Id from Opportunity where Id =: sr_opp.getId() limit 1];
		
		OppForNatSalesHelperClass.setIsInsert(false);
		o_saved.Name = 'testOppForNatSalesHelperClass 2';
		try{
			update o_saved;
		}catch(Exception ex){
			System.assert(ex.getMessage().contains(OppForNatSalesHelperClass.errorMessage));
		}
		
		addOpportunityProduct(sr_opp.getId(),'test prod name');
		
		OppForNatSalesHelperClass.setIsInsert(false);
		o_saved.Name = 'testOppForNatSalesHelperClass 3';
		update o_saved;
	}
	
	public static testMethod void OpportunityProductCheckForAASTriggerTester(){
		Opportunity o = new Opportunity();
		o.Name = 'test OpportunityProductCheckForAASTriggerTester';
		o.StageName = 'Test name';
		o.CloseDate = Date.today();
		Database.Saveresult sr = Database.insert(o);
		
		addOpportunityProduct(sr.getId(), 'test prod name');
		
		Opportunity o_rst = [select Product_List__c from Opportunity where Id =: sr.getId() limit 1];
		//System.assertEquals('"test prod name"', o_rst.Product_List__c);
	}
	
	private static void addOpportunityProduct(ID oppId, String prodName){
		Product2 prod = new Product2();
		prod.Name = prodName;
		prod.isActive = true;
		Database.SaveResult sr_prod = Database.insert(prod,false);
		System.assertEquals(true, sr_prod.isSuccess());
		
		Pricebook2 standardPB = [Select Id from Pricebook2 where IsStandard = true limit 1];
		PricebookEntry starndEntry = new PricebookEntry();
		starndEntry.Pricebook2Id = standardPB.Id;
		starndEntry.Product2Id = sr_prod.getId();
		starndEntry.UnitPrice = 1;
		starndEntry.IsActive = true;
		Database.SaveResult sr_starndEntry = Database.insert(starndEntry,false);
		for(Database.Error er : sr_starndEntry.getErrors()){
			System.debug(' sr_starndEntry error = ' + er.getMessage());
		}
		System.assertEquals(true, sr_starndEntry.isSuccess());
		
		Pricebook2 pricebook = new Pricebook2();
		pricebook.Name = 'test pricebook name';
		pricebook.IsActive = true;
		Database.SaveResult sr_pb = Database.insert(pricebook,false);
		System.assertEquals(true, sr_pb.isSuccess());
		
		PricebookEntry pbentry = new PricebookEntry();
		pbentry.Pricebook2Id = sr_pb.getId();
		pbentry.Product2Id = sr_prod.getId();
		pbentry.UnitPrice = 1;
		pbentry.IsActive = true;
		pbentry.UseStandardPrice = false;
		Database.SaveResult sr_pbentry = Database.insert(pbEntry,false);
		for(Database.Error er : sr_pbentry.getErrors()){
			System.debug(' sr_pbentry error = ' + er.getMessage());
		}
		System.assertEquals(true, sr_pbentry.isSuccess());
		
		OpportunityLineItem oppItem = new OpportunityLineItem();
		oppItem.OpportunityId = oppId;
		oppItem.Quantity = 1;
		oppItem.TotalPrice = 100;
		oppItem.PricebookEntryId = sr_pbentry.getId();
		Database.SaveResult sr_oppitem = Database.insert(oppItem,false);
		System.assertEquals(true, sr_oppitem.isSuccess());
	}

	static testMethod void testQuoteUpdate() {
		Account a = new Account();
		a.RecordTypeId = RecordTypeHelper.GetRecordTypeIDByDevName('Account',  'Advanced_Ad_Solutions');
		a.Name = 'testQuoteUpdate Acc';
		a.Billing_Contact__c = 'Billing_Contact__c';
		a.Contact_Phone__c = 'Contact_Phone__c';
		a.Contact_Fax__c = 'Contact_Fax__c';
		a.Contact_Email__c = 'Contact_Email__c@c.com';
		a.Payment_Schedule__c = 'Monthly Invoice';
		a.Payment_Method__c = 'Cash';
		Database.Saveresult save_a = Database.insert(a);
		
		Opportunity o = new Opportunity();
		o.RecordTypeId = RecordTypeHelper.GetRecordTypeID('Opportunity',  'Advanced Ad Solutions');
		o.Name = 'testQuoteUpdate Opp';
		o.AccountId = save_a.getId();
		o.StageName = 'Beginning';
		o.CloseDate = Date.today().addDays(10);
		o.LeadSource = 'Web site';
		Database.Saveresult save_o = Database.insert(o);
		
		Quote q = new Quote();
		q.OpportunityId = save_o.getId();
		q.Name = 'testQuoteUpdate Quote';
		q.Status = 'Started';
		Database.Saveresult save_q = Database.insert(q);
		
		Quote rst_q = [select Status from Quote where Id =: save_q.getId() limit 1];
		rst_q.Status = 'Quote Returned';
		update rst_q;

		Opportunity rst_o = [select Quote_Provided_To_Sales_Date__c, StageName from Opportunity where Id =: save_o.getId() limit 1];
		
		System.assertEquals(Date.today() , rst_o.Quote_Provided_To_Sales_Date__c);
		System.assertEquals('Proposal Returned to AE' , rst_o.StageName);
		
	}
	
    public static testMethod void schedulerTest() {
    	Test.startTest();
    	AASOpportunityMonthlyUpdate a0 = new AASOpportunityMonthlyUpdate();
    	String sch0 = AASOpportunityMonthlyUpdate.CRON_EXP0;
    	String jobId;
    	jobId = System.schedule('Test Schedule Job0', sch0, a0);
    	CronTrigger ct = [SELECT id, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :jobId];
    	System.assertEquals(AASOpportunityMonthlyUpdate.CRON_EXP0, ct.CronExpression); 
    	System.assertEquals(0, ct.TimesTriggered);
    	Test.stopTest();
    }
    
    /*
       Contact Trigger Test
    */
    private static Account createAccountByRecordTypeName(String rtName)
    {
       Account a = new Account();
       a.Name = 'Test Account';
       a.RecordTypeId = RecordTypeHelper.GetRecordTypeID('Account', rtName);
       
       return a;
    }
    
    private static Contact createContactByRecordTypeName(String rtName)
    {
       Contact c = new Contact();
       c.FirstName = 'Contact';
       c.LastName = 'Test';
       c.Phone = '(000)123-4567';
       c.RecordTypeId = RecordTypeHelper.GetRecordTypeID('Contact', rtName);
       
       return c;
    }
    
    private static Account initIOGAccountTest()
    {
       Account a = createAccountByRecordTypeName('CSS Customer');
       insert a;
       
       Map<String,List<String>> cToCreate = new Map<String,List<String>>
       {
          'ab234l' => new List<String>{OppForNatSalesHelperClass.CONTACT_RT_NAME_IOG_CONTACT,'ab@cd.com'},
          'cd454l' => new List<String>{OppForNatSalesHelperClass.CONTACT_RT_NAME_IOG_CONTACT,'ab@att-temp.com'},
          'ef667l' => new List<String>{OppForNatSalesHelperClass.CONTACT_RT_NAME_ATT_PROFESSIONAL,'cd@oor.com'},
          'gf098k' => new List<String>{OppForNatSalesHelperClass.CONTACT_RT_NAME_ATT_PROFESSIONAL,'ge@yellowpages-temp.com'}
       };
       
       List<Contact> cList = new List<Contact>();
       for(String attuid : cToCreate.keyset())
       {
          List<String> cParams = cToCreate.get(attuid);
          Contact c = createContactByRecordTypeName(cParams[0]);
          c.AccountId = a.Id;
          c.Email = cParams[1];
          c.ATTUID__c = attuid;
          cList.add(c);
       }
       
       insert cList;
       
       // Contacts relationship is not writable, have to re-query
       a = [SELECT RecordTypeId, RecordType.Name, Customer_ID__c,
           (SELECT Email, ATTUID__c, RecordType.Name, RecordTypeId FROM Contacts) 
            FROM Account WHERE ID = :a.Id][0];
       
       return a;
    }
    
    /* AD-24884 test */
    @isTest
    private static void validateIOGContacts()
    {
    	 Account a = initIOGAccountTest();
    	 
    	 // validate 1
    	 Contact iogContact = createContactByRecordTypeName(OppForNatSalesHelperClass.CONTACT_RT_NAME_IOG_CONTACT);
    	 iogContact.AccountId = a.Id;
    	 iogContact.Email = 'xxx' + OppForNatSalesHelperClass.attEmployeeEmails[0];
    	 Database.Saveresult result = Database.insert(iogContact,false);
    	 
    	 system.assert(result.isSuccess() == false && result.getErrors()[0].getMessage() == OppForNatSalesHelperClass.IOG_CONTACT_WITH_ATTEMPLOYEE_EMAIL_MESSAGE);
    	 
    	 iogContact.Email = 'xxx@att-temp.com';
    	 result = Database.insert(iogContact); // should be succesfully inserted
    	 
    	 iogContact.Email = 'xxx' + OppForNatSalesHelperClass.attEmployeeEmails[1];
    	 result = Database.update(iogContact,false);
    	 
    	 system.assert(result.isSuccess() == false && result.getErrors()[0].getMessage() == OppForNatSalesHelperClass.IOG_CONTACT_WITH_ATTEMPLOYEE_EMAIL_MESSAGE);
    	 
    	 // validate 2
    	 Contact attContact = createContactByRecordTypeName(OppForNatSalesHelperClass.CONTACT_RT_NAME_ATT_PROFESSIONAL);
    	 attContact.AccountId = a.Id;
    	 attContact.Email = 'ge@yellowpages-temp.com';
    	 result = Database.insert(attContact,false);
    	 
    	 system.debug(result);
    	 system.assert(result.isSuccess() == false); 
    	 system.assert(result.getErrors()[0].getMessage() == OppForNatSalesHelperClass.ATT_PROFESSIONAL_WITH_DUP_MESSAGE);
    	 
    	 attContact.Email = 'ab@att-temp-2.com';
    	 attContact.ATTUID__c = 'gf098k';
    	 result = Database.insert(attContact,false);
    	 
    	 system.assert(result.isSuccess() == false && result.getErrors()[0].getMessage() == OppForNatSalesHelperClass.ATT_PROFESSIONAL_WITH_DUP_MESSAGE);
    	 
    	 attContact.ATTUID__c = 'cn484l';
    	 result = Database.insert(attContact); // should be succesfully inserted
    	 
    	 attContact.ATTUID__c = 'gf098k';
    	 result = Database.update(attContact,false);
    	 
    	 system.assert(result.isSuccess() == false && result.getErrors()[0].getMessage() == OppForNatSalesHelperClass.ATT_PROFESSIONAL_WITH_DUP_MESSAGE);
    	 
    	 attContact.ATTUID__c = 'cn484l';
    	 attContact.Email = 'ge@yellowpages-temp.com';
    	 result = Database.update(attContact,false);
    	 
    	 system.assert(result.isSuccess() == false && result.getErrors()[0].getMessage() == OppForNatSalesHelperClass.ATT_PROFESSIONAL_WITH_DUP_MESSAGE);
    	 
    	 attContact.Email = 'ab@att-temp-2.com';
    	 
    	 // validate 3
    	 //a.Customer_ID__c = '123345';
    	 a.CSS_CustomerID__c = '123345';
    	 update a;
    	 
    	 result = Database.update(attContact,false);

    	 system.assert(result.isSuccess() == false && result.getErrors()[0].getMessage() == OppForNatSalesHelperClass.ATT_PROFESSIONAL_WITH_CUSTOMER_ACCOUNT_MESSAGE);   	 
    }
    /* end */
    
    /* AD-31013 */
    static testMethod void testCaseProductForNato() {
    	Case c = new Case();
    	c.RecordTypeId = RecordTypeHelper.GetRecordTypeIdByDevName('Case',  'National_Ops_Insertion_Order');
    	c.Status = 'Ready for OV';
    	c.Workflow_Type__c = 'Subscription';
    	insert c;
    	Case_Product__c cp = new Case_Product__c();
    	cp.Case__c = c.Id;
    	cp.Advertiser__c = 'Test A';
    	cp.Value__c = 1000;
    	cp.Customer_ID__c = '1234567890';
    	insert cp;
    	Case rst = [select id, AF_Customer_ID__c from Case where id =: c.Id limit 1];
    	System.assertEquals(rst.AF_Customer_ID__c, cp.Customer_ID__c);
    	
    	cp.Customer_ID__c = '0987654321';
    	update cp;
    	
    	rst = [select id, AF_Customer_ID__c from Case where id =: c.Id limit 1];
    	System.assertEquals(rst.AF_Customer_ID__c, cp.Customer_ID__c);
    	
    	delete cp;
    	rst = [select id, AF_Customer_ID__c from Case where id =: c.Id limit 1];
    	System.assertEquals(rst.AF_Customer_ID__c, null);
    }
    
    static testMethod void testNatoCaseCopyWebEmail() {
    	Case c = new Case();
    	c.RecordTypeId = RecordTypeHelper.GetRecordTypeIdByDevName('Case',  'National_Ops_Insertion_Order');
    	c.Status = 'Ready for OV';
    	c.Origin = 'Email';
    	c.SuppliedEmail = 'abcdefg.hijklmnopqrstuvwxyz!#$%&\'*/=?^_+-`{|}~0123456789@acme-inc.com.cn.xyz9000';
    	insert c;    	
    	Case rst = [select Case_Contact_Email__c, SuppliedEmail from Case where id =: c.Id];
    	System.assertEquals(rst.SuppliedEmail, rst.Case_Contact_Email__c);
    }
}